package com.pt25.study.example.interfaces.facade.test;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.pt25.base.dep.log.Log;
import com.pt25.base.exception.BizException;
import com.pt25.base.model.common.util.compress.FlaterCompressService;
import com.pt25.base.res.ResBody;
import com.pt25.base.util.ConditionUtil;
import com.pt25.base.util.InflaterUtil;
import com.pt25.base.util.JsonUtil;
import com.pt25.study.example.interfaces.vo.TestObjVo;
import com.pt25.study.example.interfaces.vo.ValidTestVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Slf4j
@Tag(name = "framework test api")
@RefreshScope
@RestController
@RequestMapping("/test-api/example")
public class FrameworkTestController {
    private final static String TEST_CONFIG_AUTO_REFRESH = "/test-config-auto-refresh";
    private final static String TEST_EXCEPTION = "/test-exception";
    private final static String TEST_GET_PROPERTIES = "/test-properties";
    private final static String TEST_OBJ_STRING_TRIM = "/test-obj-string-tim";
    private final static String TEST_FLATER_COMPRESS = "/test-flater-compress";
    private final static String TEST_VALIDATOR = "/test-validator";
    private final static String TEST_GUAVA_LOCAL_CACHE = "/test-guava-local-cache";
    private final static String TEST_CONDITION_UTIL = "/test-condition-util";

    @Value("${pt.config-refresh:default_value}")
    private String configValue;


    @Resource
    private FlaterCompressService flaterCompressService;

    @Operation(summary = "测试配置动态刷新")
    @GetMapping(TEST_CONFIG_AUTO_REFRESH)
    public String testConfigAutoRefresh() {
        return configValue;
    }

    @Operation(summary = "测试全局异常拦截")
    @GetMapping(TEST_EXCEPTION)
    public String testException() {
        throw new BizException("测试全局异常拦截error");
    }

    @Operation(summary = "测试配置读取")
    @GetMapping(TEST_GET_PROPERTIES)
    public String testGetProperties() {
        return "ok";
    }

    @Operation(summary = "测试对象中字符串统一trim")
    @PostMapping(TEST_OBJ_STRING_TRIM)
    public String testObjStringTrim(@RequestBody TestObjVo testObjVo) {
        testObjVo.setTest(testObjVo.getTest() + "###");
        return JsonUtil.toJson(testObjVo);
    }


    @Operation(summary = "测试flater压缩和解压缩")
    @PostMapping(TEST_FLATER_COMPRESS)
    public ResBody testFlaterCompress(@RequestBody TestObjVo testObjVo) throws Exception {
        String compress = InflaterUtil.compress(testObjVo.getTest());
        String uncompress = InflaterUtil.uncompress(compress);
        String compress1 = flaterCompressService.compress(testObjVo.getTest());
        String uncompress1 = flaterCompressService.uncompress(compress1);
        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("test", testObjVo.getTest());
        returnMap.put("test size", testObjVo.getTest().getBytes().length);
        returnMap.put("compress size", compress.getBytes().length);
        returnMap.put("uncompress size", uncompress.getBytes().length);
        returnMap.put("compress1 size", compress1.getBytes().length);
        returnMap.put("uncompress1 size", uncompress1.getBytes().length);
        returnMap.put("uncompress test", uncompress);
        returnMap.put("uncompress1 test", uncompress1);
        return ResBody.builder().build().ok(returnMap);
    }


    @Log(value = "参数...")
    @Operation(summary = "测试自定义validator注解")
    @PostMapping(TEST_VALIDATOR)
    public ResBody testValidator(@RequestBody @Validated ValidTestVo validTestVo) throws Exception {
        log.info("validTestVo={}", JsonUtil.toJson(validTestVo));
        return ResBody.builder().build().ok();
    }

    @Operation(summary = "测试guava本地缓存")
    @PostMapping(TEST_GUAVA_LOCAL_CACHE)
    public ResBody testGuavaLocalCache() {
        // 创建一个缓存实例
        Cache<String, String> cache = CacheBuilder.newBuilder()
                .expireAfterWrite(10, TimeUnit.MINUTES)  // 设置缓存过期时间为10分钟
                .build();
        // 添加缓存条目
        cache.put("key1", "value1");
        cache.put("key2", "value2");
        // 访问缓存条目
        String value1 = cache.getIfPresent("key1");
        System.out.println("key1 value: " + value1);
        // 模拟等待一段时间，让缓存过期
        try {
            TimeUnit.MINUTES.sleep(11);
        } catch (InterruptedException e) {
            log.error(e.getMessage());
        }
        // 访问缓存条目（过期后将返回null）
        String expiredValue = cache.getIfPresent("key1");
        System.out.println("Expired key1 value: " + expiredValue);
        return ResBody.builder().build().ok();
    }

    @Operation(summary = "测试ConditionUtil工具使用")
    @PostMapping(TEST_CONDITION_UTIL)
    public ResBody testConditionUtil(Integer rel, String name, Integer age) {

        @Data
        class OperationData {
            private String operation;
        }
        //1、创建比较条件
        OperationData operationData1 = new OperationData();
        operationData1.setOperation("operation1");
        ConditionUtil.Condition<OperationData> condition1 = new ConditionUtil.Condition<>();
        condition1.setField("name");
        condition1.setCompare(ConditionUtil.Compare.EQ);
        condition1.setValueType(ConditionUtil.ValueType.STR);
        condition1.setValueData("hzc");
        condition1.setOperation(operationData1);

        OperationData operationData2 = new OperationData();
        operationData2.setOperation("operation2");
        ConditionUtil.Condition<OperationData> condition2 = new ConditionUtil.Condition<>();
        condition2.setField("age");
        condition2.setCompare(ConditionUtil.Compare.GT);
        condition2.setValueType(ConditionUtil.ValueType.NUM);
        condition2.setValueData(20);
        condition2.setOperation(operationData2);

        OperationData operationData3 = new OperationData();
        operationData3.setOperation("operation3");
        ConditionUtil.Condition<OperationData> condition = new ConditionUtil.Condition<>();
        condition.setRel(rel == 0 ? ConditionUtil.Rel.OR : ConditionUtil.Rel.AND);
        condition.setOperation(operationData3);
        condition.setConditions(List.of(condition1, condition2));
        //2、创建比较数据
        Map<String, Object> compareData = new HashMap<>();
        compareData.put("name", name);
        compareData.put("age", age);
        //3、验证条件
        ConditionUtil.ConditionResult<OperationData> operationDataConditionResult = ConditionUtil.checkCondition(condition, compareData);
        return ResBody.builder().build().ok(operationDataConditionResult);
    }

}
